﻿/*************************************************************************************
 * 工    具：  HK_ResetName
 * 
 * 描    述：  本工具提供了两大主要功能：
 *            1.替换选中物体名称中的特定字符串
 *            2.对选中物体进行重命名。
 *            该工具使得开发者可以更高效地管理游戏对象的命名，提高项目的组织和维护便利性。
 * 
 * 版    本：  V1.0
 * 作    者：  京产肠饭
 * 
 * 创    建：  2021/08/26  V1.0
 * 
 * 链    接：  https://gitee.com/JingChanChangFan/hk_-unity-tools
*************************************************************************************/

using System;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;

namespace HKTools
{
    public class HK_ResetName : EditorWindow
    {
        // 当前选择的功能
        int popupIndex = 1;
        readonly string[] popupOptions = { "Replace", "Rename" };

        // 查找输入框
        string findInput;
        // 替换输入框
        string replaceInput;
        // 新名字输入框
        string newNameInput;
        // 起始编号
        int startIndexInput;

        GameObject[] selectedObjs;
        static MethodInfo clearMethod = null;

        [MenuItem("HKTools/Reset Name (重命名工具)", priority = HK_MenuPriority.HK_ReName)]
        static void Init()
        {
            // 弹出窗口
            HK_ResetName resetNameWindow = GetWindow<HK_ResetName>("ResetName");
            resetNameWindow.Show();
        }

        void OnGUI()
        {
            EditorGUILayout.Space(10);

            EditorGUILayout.LabelField("Tips:");
            EditorGUILayout.LabelField("本工具提供了以下主要功能：替换选中物体名称中的特定字符串以及重命名选中物体。其使用方式如下：");
            EditorGUILayout.LabelField("1.在Unity编辑器的Hierarchy窗口中，选择需要操作的物体");
            EditorGUILayout.LabelField("2.在工具界面中，从“Replace”和“Rename”两种模式中进行选择");
            EditorGUILayout.LabelField("3.Replace 模式：输入待查找的字符串和替换的字符串，工具将扫描所有选中物体的名称，并将符合条件的部分替换为新字符串。");
            EditorGUILayout.LabelField("4.Rename 模式：输入新的名称和起始编号，工具将对选中物体进行重命名，并按编号顺序进行排序。");
            EditorGUILayout.LabelField("5.如需将所有选中物体修改为统一命名，直接在Inspector界面的输入框中输入目标名称，将自动替换所有选中物体的名称为统一名称，无需使用本工具。");

            EditorGUILayout.Space(2);

            EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);

            EditorGUILayout.Space(3);

            popupIndex = EditorGUILayout.IntPopup("请选择功能:", popupIndex, popupOptions, new int[] { 0, 1 });

            EditorGUILayout.Space();

            if (popupIndex == 0)
                RenderReplaceGUI();  // 替换功能
            else
                RenderRenameGUI();  // 重命名功能

            Repaint();// 实时刷新窗口
        }

        // 绘制 替换功能
        void RenderReplaceGUI()
        {
            findInput = EditorGUILayout.TextField("查找字段为:", findInput);
            EditorGUILayout.Space();
            replaceInput = EditorGUILayout.TextField("替换为:", replaceInput);
            EditorGUILayout.Space();

            //创建一个按钮
            if (GUILayout.Button("替换", GUILayout.Width(60)))
            {
                Undo.RecordObjects(Selection.objects, "Replace");
                FindAndReplaceName(findInput, replaceInput);
            }
        }

        // 绘制 重命名功能
        void RenderRenameGUI()
        {
            newNameInput = EditorGUILayout.TextField("新名称:", newNameInput);
            EditorGUILayout.Space();
            startIndexInput = EditorGUILayout.IntField("起始序号：", startIndexInput);
            EditorGUILayout.Space();

            //创建一个按钮
            if (GUILayout.Button("重命名", GUILayout.Width(60)))
            {
                Undo.RecordObjects(Selection.objects, "Rename");
                SetNewName(newNameInput);
            }
        }

        // 查找并替换名称
        void FindAndReplaceName(string findName, string replaceName)
        {
            ClearConsole();

            //获取所选中物体的数组
            selectedObjs = Selection.gameObjects;

            if (selectedObjs.Length == 0)
            {
                Debug.LogError("错误: 没有选中任何物体!");
                return;
            }

            if (string.IsNullOrEmpty(findName) || string.IsNullOrEmpty(replaceName))
            {
                Debug.LogError("错误: 值不能为空!");
                return;
            }

            var affectedObjs = selectedObjs.Where(obj => obj.name.Contains(findName)).ToList();

            if (affectedObjs.Count == 0)
            {
                Debug.LogWarning("没有找到符合条件的物体!");
                return;
            }

            foreach (var obj in affectedObjs)
            {
                string oldName = obj.name;
                obj.name = obj.name.Replace(findName, replaceName);
                Debug.Log($"替换：{oldName} -> {obj.name}");
            }

            Selection.objects = affectedObjs.ToArray();
        }

        // 设置新名称
        void SetNewName(string newName)
        {
            //前期准备工作
            ClearConsole();

            //获取所选中物体的数组
            selectedObjs = Selection.gameObjects;

            if (selectedObjs.Length == 0)
            {
                Debug.LogError("错误: 没有选中任何物体!");
                return;
            }

            if (string.IsNullOrEmpty(newName))
            {
                Debug.LogError("错误: 值不能为空!");
                return;
            }

            // selectedObjs 的排序可能不是顺序从上往下的，所以得先重新排序下
            var sortedObjs = selectedObjs.OrderBy(obj => obj.transform.GetSiblingIndex()).ToList();

            for (int i = 0; i < sortedObjs.Count; i++)
            {
                string oldName = sortedObjs[i].name;
                sortedObjs[i].name = $"{newName}_{startIndexInput + i}";
                Debug.Log($"重命名: {oldName} -> {sortedObjs[i].name}");
            }
        }

        // 清空控制台日志信息
        void ClearConsole()
        {
            if (clearMethod == null)
            {
                Type log = typeof(EditorWindow).Assembly.GetType("UnityEditor.LogEntries");
                clearMethod = log.GetMethod("Clear");
            }
            clearMethod?.Invoke(null, null);
        }
    }
}